package com.simblog.interceptor;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.simblog.common.ClientParameter;
import com.simblog.common.constants.Constants;
import com.simblog.common.utils.ClientParameterUtil;
import com.simblog.common.utils.PropertiesUtil;

public class CommonInterceptor extends HandlerInterceptorAdapter {

	private static final Logger logger = LoggerFactory.getLogger(CommonInterceptor.class);
	
	private static String processEnv = PropertiesUtil.getString(PropertiesUtil.load("global.properties"), "process.env");

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		super.afterCompletion(request, response, handler, ex);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		String url = request.getQueryString() != null ? request.getRequestURI() + "?" + request.getQueryString()
				: request.getRequestURI();
		logger.info("接口访问地址：{}", url);
		
		if("development".equals(processEnv)){//开发环境，绕过检测接口必传参数
			return true;
		}

		Enumeration<String> names = request.getParameterNames();
		Map<String, String> params = new TreeMap<String, String>();

		while (names.hasMoreElements()) {
			String name = names.nextElement();
			logger.info("接口传递的参数，{}={}", new Object[] { name, request.getParameter(name) });
			params.put(name, request.getParameter(name));
		}

		if (!Constants.CLIENT_PARAMETER.isEmpty()) {
			for (String key : Constants.CLIENT_PARAMETER.keySet()) {
				if (params.get(key) != null && !StringUtils.isBlank(params.get(key))) {
					continue;
				} else {
					logger.error("接口必传参数{}没有传",key);
					String requestType = request.getHeader("X-Requested-With");
					if (requestType != null && requestType.equalsIgnoreCase("XMLHttpRequest")) {
						response.addHeader("loginStatus", "accessDenied");
						response.sendError(HttpServletResponse.SC_FORBIDDEN);
						return false;
					} else {
						// 跳转到出错页面
						response.sendRedirect(request.getContextPath() + "/p/error/client_parameter_error.jhtml");
						return false;
					}
				}
			}
		}

		// 判断请求的有效期
		Long clientTimestamp = Long.valueOf(params.get("timestamp"));
		Long serverTimestamp = System.currentTimeMillis();

		long diff = (clientTimestamp - serverTimestamp) / (60 * 1000);
		logger.info("客户端时间和服务器当前时间只差,diff={}", diff);

		if (diff > 5 || diff < -5) {
			logger.info("客户端时间毫秒数,clientTimestamp={}", clientTimestamp);
			logger.info("服务器时间毫秒数,serverTimestamp={}", serverTimestamp);
			logger.error("客户端时间与服务器时间只差大于5分钟，请检查客户端时间");
			response.sendRedirect(request.getContextPath() + "/p/error/client_timestamp_error.jhtml");
			return false;
		} 
		
		//签名验证
		ClientParameter clientParameter = new ClientParameter();
		clientParameter.setClient_type(params.get("client_type"));
		params.remove("client_type");
		clientParameter.setClient_version(params.get("client_version"));
		params.remove("client_version");
		clientParameter.setImei(params.get("imei"));
		params.remove("imei");
		clientParameter.setOs_version(params.get("os_version"));
		params.remove("os_version");
		clientParameter.setTimestamp(params.get("timestamp"));
		params.remove("timestamp");
		if(params.containsKey("token")){
			clientParameter.setToken(params.get("token"));
			params.remove("token");
		}
		String sign = params.get("sign");
		params.remove("sign");
		boolean flag = ClientParameterUtil.validateSign(params, clientParameter, sign);
		
		
		logger.info("签名结果校验：{}",flag);
		
		if(!flag){
			response.sendRedirect(request.getContextPath() + "/p/error/sign_validate_error.jhtml");
		}
		return flag;
	}

}
